package com.em.mission;

import android.content.Context;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * Created by admin on 16/9/10.
 */

public class MissionQueue extends MissionItem implements MissionListener,MissionResultListener {

//    private static MissionQueue instance;
    private LinkedList<Mission> linkedItems;
    private ArrayList<Mission>  arrayList;
    private int                 missionCount;

    private onMissionQueueListener listener;

    public MissionQueue(Context mContext, String name) {
        super(mContext, name);
        linkedItems = new LinkedList<Mission>();
        arrayList   = new ArrayList<Mission>();
        missionCount = 0;
    }


//    public static MissionQueue getInstance(Context mContext, String name){
//        if (instance == null){
//            synchronized (MissionQueue.class){
//                instance = new MissionQueue(mContext, name);
//            }
//        }
//        return instance;
//    }


    public MissionQueue addMission(Mission item){
        arrayList.add(item);
        linkedItems.add(item);
        missionCount ++;
        return this;
    }

    public MissionQueue addMissions(List<Mission> items){
        if (items!=null && !items.isEmpty()){
            arrayList.addAll(items);
            linkedItems.addAll(items);
            missionCount = missionCount + items.size();
        }
        return this;
    }

    public boolean offerLast(Mission m){
        return linkedItems.offerLast(m);
    }

    public boolean offerFirst(Mission m){
        return linkedItems.offerFirst(m);
    }

    public boolean retryAllMission(){
        if (arrayList==null || arrayList.isEmpty())
            return false;
        linkedItems.clear();
        linkedItems.addAll(arrayList);
        missionCount =  arrayList.size();
        executeMission(getLinkedTop(linkedItems));
        return true;
    }

    public boolean isLastMission(Mission m){
        if (linkedItems.isEmpty() || linkedItems == null)
            return false;
        return linkedItems.getLast() == m;
    }

    public void start(onMissionQueueListener listener){
        this.listener = listener;
        start(this, this);
    }


    @Override
    public void beforeExecuteListener(Mission mission) {
    }

    @Override
    public void onExecute(Mission mission) {
        Mission firstMission = getLinkedTop(linkedItems);
        if (firstMission == null){
            return;
        }
        firstMission.isExecute = false;
        firstMission.start(this);
    }

    private Mission getLinkedTop(LinkedList<Mission> linkedItems) {
        if (linkedItems == null ||linkedItems.isEmpty()){
            return null;
        }
        else{
            return linkedItems.peekFirst();
        }
    }

    @Override
    public void afterExecute(Mission mission) {

    }

    @Override
    public void executeSuccess(Object result, Mission mission) {
        mission.isExecute = true;
        if (listener!=null){
            if (mission != this){
                missionCount--;
                listener.onMissionItemSuccess(this, mission, result);
            }

            if (missionCount<=0){
                listener.onMissionQueComplete(this);
            }
        }
    }

    public void executeNextMission(MissionQueue queue, Mission completedMission) {
        Mission next = getNextMission(queue.linkedItems,completedMission);
        if (next!=null){
            executeMission(next);
        }
    }

    private Mission getNextMission(LinkedList<Mission> linkedItems, Mission completedMission) {
        if (linkedItems.contains(completedMission)){
            int i = linkedItems.indexOf(completedMission);
            if (i+1 < linkedItems.size()){
                Mission nextMission = linkedItems.get(i + 1);
                linkedItems.remove(completedMission);
                return nextMission;
            }
        }
        return getNextMission(linkedItems);
    }

    public MissionQueue removeMission(Mission m){
        if (linkedItems == null || linkedItems.isEmpty())
            return this;
        if (linkedItems.contains(m)){
            linkedItems.remove(m);
            missionCount--;
        }
        return this;
    }

    //从队列获取下一个的任务,根据Mission的是否完成来判断
    public void executeNextMission(MissionQueue queue){
        Mission next = getNextMission(queue.linkedItems);
        if (next!=null){
            executeMission(next);
        }
    }

    private Mission getNextMission(LinkedList<Mission> linkedItems) {
        for (Mission mission : linkedItems){
            if (!mission.isExecute){
                return mission;
            }else{
                linkedItems.remove();
            }
        }
        return null;
    }



    private void executeMission(Mission mission) {
        mission.start(this);
    }

    @Override
    public void executeFaile(Mission mission) {
        mission.isExecute = false;

        if (listener!=null){
            if (mission != this){
                listener.onMissionItemFaile(this, mission, "执行一项失败");
            }

            if (isLastMission(mission) && missionCount==arrayList.size()){
                listener.onMissionQueAllFaile(this);
            }
        }
    }

    public interface onMissionQueueListener{
        public void onMissionItemSuccess(MissionQueue queue, Mission item, Object successInfo);
        public void onMissionItemFaile(MissionQueue queue, Mission item, Object faileInfo);
        public void onMissionQueComplete(MissionQueue queue);
        public void onMissionQueAllFaile(MissionQueue queue);
    }
}
